home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / cw_orient.pro < prev    next >
Text File  |  1997-07-08  |  10KB  |  321 lines

  1. ; $Id: cw_orient.pro,v 1.6 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1992-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5.  
  6. PRO drawbox, state, FINAL = FINAL
  7.  
  8.     ; This routine is responsible for drawing the cube when the
  9.     ; cw_orient compound widget is in the trackball mode.  When 
  10.     ; the FINAL keyword is set, the view is first erased and then
  11.     ; the origin indicator is added.
  12.  
  13.   COMMON CW_ORIENT_BOX, box, faces, norms
  14.  
  15.   wind = !D.WINDOW                ; set to the view window and
  16.   wset, state.trackball                ; make sure to save the old
  17.  
  18.   IF (KEYWORD_SET(final)) THEN ERASE
  19.  
  20.   IF ( NOT(KEYWORD_SET(box))) THEN BEGIN    ; build the face vertices
  21.                         ; topology and normals only
  22.                         ; once
  23.     verts = [[.15, .15, .15],[.15, .15, .85],[.15, .85, .85],[.15, .85, .15], $
  24.          [.85, .15, .15],[.85, .15, .85],[.85, .85, .85],[.85, .85, .15]]
  25.  
  26.     faces = [[0,1,2,3,0], $
  27.              [1,2,6,5,1], $
  28.              [4,5,6,7,4], $
  29.              [4,7,3,0,4], $
  30.              [2,6,7,3,2], $
  31.              [1,5,4,0,1]]
  32.  
  33.     norms = [[-1, 0, 1, 0, 0, 0, 0], $        ; The last entry in the norms
  34.          [0, 0, 0, 0, 1, -1, 0], $        ; is the origin.  Each normal
  35.          [0, 1, 0, -1, 0, 0, 0], $        ; is a vector from the origin
  36.          [1, 1, 1, 1, 1, 1, 1 ]]         ; to the endpoint in +/- XYZ.
  37.   ENDIF
  38.   ns = norms # !P.T                ; Translate the norms for the
  39.                         ; current !P.T
  40.   FOR i = 0, 5 DO BEGIN
  41.     IF (ns[6,2] - ns[i,2] LT 0) THEN $        ; Compute the Z component of
  42.     PLOTS, verts[*, faces[*,i]], $        ; each normal and if it is less
  43.         /T3D, /NORMAL, $        ; than zero, the cooresponding
  44.         COLOR = !D.N_COLORS / 2        ; face can be seen so draw it.
  45.   ENDFOR
  46.  
  47.   IF (KEYWORD_SET(FINAL)) THEN BEGIN        ; If a final drawing, then
  48.     plots, [.15, .15, .15], $            ; draw the little origin 
  49.        [.25, .15, .15], $            ; indicator.
  50.        [.15, .15, .25], /T3D, /NORMAL
  51.     plots, [.25, .15], $
  52.        [.15,.15], $
  53.        [.15,.15], /T3D, /NORMAL
  54.   ENDIF
  55.  
  56.   WSET, wind
  57. END ; end of drawbox routine
  58.  
  59. ;---------------------------------------------------------------------------
  60.  
  61. function CW_ORIENT_EVENT, ev
  62.  
  63.   COMMON CW_OR_PRIVATE, scaler
  64.   COMMON CW_TMP, xlast, zlast, xrot, zrot
  65.  
  66.   base = ev.handler
  67.   stash = WIDGET_INFO(base, /CHILD)
  68.   WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
  69.  
  70.  
  71.   CASE ev.id OF
  72.  
  73.     state.modemenu: BEGIN
  74.  
  75.       CASE ev.value OF
  76.  
  77.     1: BEGIN; If slider mode was selected, map the sliders and set current.
  78.             IF (state.currentbase NE state.slidebase) THEN BEGIN
  79.           WIDGET_CONTROL, state.slidebase, MAP = 1
  80.           WIDGET_CONTROL, state.currentbase, MAP = 0
  81.           state.currentbase = state.slidebase
  82.         ENDIF
  83.         GOTO, SWALLOW_EV_RET
  84.       END
  85.  
  86.     2: BEGIN; If trackball mode was selected, make sure window id is known
  87.         IF (state.trackballid NE state.currentbase) THEN BEGIN
  88.           WIDGET_CONTROL, state.trackbase, MAP = 1
  89.           WIDGET_CONTROL, state.currentbase, MAP = 0
  90.           state.currentbase = state.trackballid
  91.           IF state.trackball EQ 0 THEN BEGIN
  92.         WIDGET_CONTROL, state.trackballid, GET_VALUE = temp
  93.         state.trackball = temp[0]
  94.           ENDIF
  95.           drawbox, state, /FINAL
  96.         ENDIF
  97.         GOTO, SWALLOW_EV_RET
  98.       END
  99.  
  100.     3: BEGIN; If reset menu selection was made.
  101.         WIDGET_CONTROL, state.xslide, GET_UVALUE = xrot
  102.         WIDGET_CONTROL, state.zslide, GET_UVALUE = zrot
  103.         t3d, /RESET, TRANSLATE = [-.5, -.5, -.5], SCALE = scaler
  104.         t3d, ROTATE = [-90, xrot, 0]
  105.         t3d, ROTATE = [zrot, 0, 0]
  106.         t3d, TRANSLATE = [.5, .5, .5]
  107.         WIDGET_CONTROL, state.xslide, SET_VALUE = xrot
  108.         WIDGET_CONTROL, state.zslide, SET_VALUE = zrot
  109.         IF (state.trackballid EQ state.currentbase) THEN $
  110.           drawbox, state, /FINAL
  111.       END
  112.     ENDCASE ; End of ev.value CASE
  113.       END ; End of case state.modemenu.
  114.  
  115.     state.trackballid: BEGIN
  116.     IF ev.press THEN BEGIN
  117.         ; Begin tracking the trackball as the mouse button is down.
  118.         ; Set the drawing mode to XOR
  119.       WIDGET_CONTROL, state.xslide, GET_VALUE = xrot
  120.       WIDGET_CONTROL, state.zslide, GET_VALUE = zrot
  121.       xlast = ev.x
  122.       zlast = ev.y
  123.       state.trackmode = 1
  124.       DEVICE, SET_GRAPHICS_FUNCTION = 6
  125.       GOTO, SWALLOW_EV_RET
  126.     ENDIF
  127.  
  128.     IF ev.release THEN BEGIN
  129.         ; Once finished tracking, do range checking and then restore
  130.         ; drawing mode and redraw the cube.
  131.       IF (xrot LT 0) THEN xrot = xrot + 360
  132.       IF (zrot LT 0) THEN zrot = zrot + 360
  133.       IF (xrot GT 360) THEN xrot = xrot - 360
  134.       IF (zrot GT 360) THEN zrot = zrot - 360
  135.       WIDGET_CONTROL, state.xslide, SET_VALUE = xrot
  136.       WIDGET_CONTROL, state.zslide, SET_VALUE = zrot
  137.         state.trackmode = 0
  138.         DEVICE, SET_GRAPHICS_FUNCTION = 3
  139.         drawbox, state, /FINAL
  140.     ENDIF
  141.  
  142.     IF state.trackmode THEN BEGIN
  143.         drawbox, state
  144.         ; For each direction, figure out the magnitude of movement
  145.         ; first and then the direction.
  146.       IF (xlast NE ev.x) THEN BEGIN
  147.           xangle = ASIN((100.0 - ABS(xlast-ev.x)) / 100.0) * 1.7
  148.         IF ((xlast - ev.x) LT 0) THEN xangle = -xangle
  149.           xlast = ev.x
  150.         ENDIF ELSE xangle = 0
  151.  
  152.       IF (zlast NE ev.y) THEN BEGIN
  153.         zangle = -ASIN((100.0 - ABS(zlast-ev.y)) / 100.0) * 1.7
  154.         IF ((zlast - ev.y) LT 0) THEN zangle = -zangle
  155.         zlast = ev.y
  156.       ENDIF ELSE zangle = 0
  157.  
  158.       xrot = xrot - xangle            ; Apply the changes to the
  159.       zrot = zrot - zangle            ; rotation values.
  160.  
  161.       t3d, /RESET, TRANSLATE = [-.5, -.5, -.5], SCALE = scaler
  162.       t3d, ROTATE = [-90, xrot, 0]
  163.       t3d, ROTATE = [zrot, 0, 0]
  164.       t3d, TRANSLATE = [.5, .5, .5]
  165.  
  166.       drawbox, state
  167.       GOTO, SWALLOW_EV_RET            ; Don't return an event until
  168.     ENDIF                    ; the user lets go.
  169.  
  170.     IF (ev.release EQ 0) THEN GOTO, SWALLOW_EV_RET
  171.       END; case state.trackballid
  172.  
  173.  
  174.     ELSE: BEGIN    ; Handle the sliders which are the only events not covered
  175.         ; above.
  176.     WIDGET_CONTROL, state.xslide, GET_VALUE = xrot
  177.     WIDGET_CONTROL, state.zslide, GET_VALUE = zrot
  178.     t3d, /RESET, TRANSLATE = [-.5, -.5, -.5], SCALE = scaler
  179.     t3d, ROTATE = [-90, xrot, 0]
  180.     t3d, ROTATE = [zrot, 0, 0]
  181.     t3d, TRANSLATE = [.5, .5, .5]
  182.       END
  183.  
  184.   ENDCASE ; End of ev.id CASE
  185.  
  186.   ev.id = base
  187.   ev.handler = 0
  188.  
  189.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  190.   RETURN, ev
  191.  
  192. swallow_ev_ret:
  193.   WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
  194.   RETURN, 0
  195.  
  196. END ; End of cw_orient_event routine.
  197.  
  198. ;---------------------------------------------------------------------------
  199.  
  200. FUNCTION CW_ORIENT, parent, UVALUE = UVALUE, XSIZE = XSIZE, YSIZE = YSIZE, $
  201.             FRAME = FRAME, AX = AX, AZ = AZ, TITLE = TITLE
  202.  
  203. ; Copyright (c) 1992, Research Systems, Inc.  All rights reserved.
  204. ;    Unauthorized reproduction prohibited.
  205. ;+
  206. ; NAME:
  207. ;    CW_ORIENT
  208. ;
  209. ; PURPOSE:
  210. ;    This compound widget provides a means to interactively adjust the
  211. ;    three dimensional drawing transformation (!P.T). The compound
  212. ;    widget only returns events when !P.T has been altered.
  213. ;
  214. ; CATEGORY:
  215. ;    Compound widgets.
  216. ;
  217. ; CALLING SEQUENCE:
  218. ;    widget = CW_ORIENT(Parent)
  219. ;
  220. ; INPUTS:
  221. ;       Parent:    The ID of the parent widget.
  222. ;
  223. ; KEYWORD PARAMETERS:
  224. ;    AX:    The initial rotation in the X direction. If not set, the 
  225. ;        default is 30 degrees.
  226. ;    AZ:    The initial rotation in the Z direction. If not set, the 
  227. ;        default is 30 degrees.
  228. ;    FRAME:    If set, a frame will be drawn around the widget. The
  229. ;        default is FRAME=0.
  230. ;    TITLE:    The title of the widget. (Default is no title.)
  231. ;    UVALUE:    The user value of the widget.
  232. ;    XSIZE:    Determines the width of the widget. The default is 100.
  233. ;    YSIZE:    Determines the height of the widget. The default is 100.
  234. ;
  235. ; OUTPUTS:
  236. ;       The ID of the created widget is returned.
  237. ;
  238. ; COMMON BLOCKS:
  239. ;    CW_OR_PRIVATE: Private to this module.
  240. ;
  241. ; SIDE EFFECTS:
  242. ;    This widget generates event structures each time a modification
  243. ;    to the orientation is made.  This widget also resets !P.T to 
  244. ;    reflect the changed orientation.
  245. ;
  246. ; MODIFICATION HISTORY:
  247. ;    August 7, 1992, SMR
  248. ;       7 April 1993, AB, Removed state caching.
  249. ;-
  250.  
  251.   COMMON CW_OR_PRIVATE, scaler
  252.  
  253.   ON_ERROR, 2                ; Return to caller.
  254.  
  255.       ; Define the contents of the state structure.
  256.  
  257.   state = {trackball:0L, trackballid:0L, $
  258.         slidebase:0L, trackbase:0L, currentbase:0L, $
  259.         xslide:0L, zslide:0L, $
  260.         trackmode:0, modemenu:0L}
  261.  
  262.       ; Set default values for the keywords.
  263.  
  264.   IF N_ELEMENTS(FRAME) NE 0    THEN frm = 1 ELSE frm = 0
  265.   IF N_ELEMENTS(UVALUE) NE 0    THEN uval = UVALUE ELSE uval = 0
  266.   IF N_ELEMENTS(XSIZE) NE 0    THEN xsi = XSIZE ELSE xsi = 120
  267.   IF N_ELEMENTS(YSIZE) NE 0    THEN ysi = YSIZE ELSE ysi = 120
  268.   IF N_ELEMENTS(AX) NE 0    THEN xrot = AX ELSE xrot = 30
  269.   IF N_ELEMENTS(AZ) NE 0    THEN zrot = AZ ELSE zrot = 30
  270.   IF N_ELEMENTS(TITLE) NE 0    THEN tit = TITLE ELSE tit = ''
  271.  
  272.   orientbase = WIDGET_BASE(parent, $
  273.             EVENT_FUNC = "CW_ORIENT_EVENT", $
  274.             UVALUE = uval, $
  275.             /COLUMN, $
  276.             FRAME = frm)
  277.  
  278.   IF (TIT NE '') THEN title = WIDGET_LABEL(orientbase, $
  279.             VALUE = TIT)
  280.  
  281.   panelbase = WIDGET_BASE(orientbase)
  282.   state.slidebase = WIDGET_BASE(panelbase, /COLUMN, MAP = 1)
  283.   state.currentbase = state.slidebase
  284.  
  285.   state.modemenu = cw_pdmenu(orientbase, [ $
  286.         {CW_PDMENU_S, flags:1, name:'Orientation'}, $
  287.         {CW_PDMENU_S, flags:0, name:'Sliders'}, $
  288.         {CW_PDMENU_S, flags:0, name:'Trackball'},   $
  289.         {CW_PDMENU_S, flags:0, name:'Reset Transformation'}], ids = i)
  290.  
  291.   state.xslide = WIDGET_SLIDER(state.slidebase, $
  292.             MIN = 0, MAX = 359, VALUE = xrot, $
  293.             TITLE = "X angle", $
  294.             XSIZE = 120, $
  295.             UVALUE = xrot)
  296.   state.zslide = WIDGET_SLIDER(state.slidebase, $
  297.             MIN = 0, MAX = 359, VALUE = zrot, $
  298.             TITLE = "Z angle", $
  299.             XSIZE = 120, $
  300.             UVALUE = zrot)
  301.  
  302.   state.trackbase = WIDGET_BASE(panelbase, MAP = 0)
  303.   state.trackballid = WIDGET_DRAW(state.trackbase, $
  304.             XSIZE = xsi, YSIZE = ysi, $
  305.             /MOTION, /BUTTON)
  306.  
  307.   WIDGET_CONTROL, WIDGET_INFO(orientbase, /CHILD), SET_UVALUE=state, /NO_COPY
  308.  
  309.   scaler = REPLICATE(1./SQRT(3),3)
  310.  
  311.   !X.S = [0, 1]
  312.   !Y.S = [0, 1]
  313.   !Z.S = [0, 1]
  314.   t3d, /RESET, TRANSLATE = [-.5, -.5, -.5], SCALE = scaler
  315.   t3d, ROTATE = [-90, xrot, 0]
  316.   t3d, ROTATE = [zrot, 0, 0]
  317.   t3d, TRANSLATE = [.5, .5, .5]
  318.  
  319.   RETURN, orientbase
  320. END
  321.